import { type CSSProperties, type ComponentInternalInstance, nextTick } from 'vue';
import { camelCase2KebabCase } from './str';
import type { $AnimationMode } from '@/mxp-ui/mxp-tool/types/interface';

/**
 * 得到dom大小
 * 注意nvue只支持 id 选择
 */
export function getDomSize(select: string, instance: ComponentInternalInstance | null): Promise<UniApp.NodeInfo> {
  return new Promise((resolve) => {
    nextTick(() => {
      uni
        .createSelectorQuery()
        .in(instance)
        .select(select)
        .boundingClientRect((rect) => {
          resolve(rect as UniApp.NodeInfo);
        })
        .exec();
    });
  });
}

/**
 * 得到标题栏高度
 * 因为 uni.getMenuButtonBoundingClientRect和 uni.getSystemInfoSync 需要延迟调用所以建议传入
 */
export function getHeaderHeight(_statusBarHeight?: number, _menuButtInfo?: UniApp.GetMenuButtonBoundingClientRectRes) {
  let headerHeight = 44;
  // #ifdef MP
  const menuButtInfo = _menuButtInfo || uni.getMenuButtonBoundingClientRect();
  const statusBarHeight = _statusBarHeight || uni.getSystemInfoSync().statusBarHeight || 0;
  // 标题栏高度，单位：px，计算公式：小胶囊高度 + (顶部距离 - 状态栏高度) * 2
  headerHeight = (menuButtInfo.top - statusBarHeight) * 2 + menuButtInfo.height;
  // #endif
  return headerHeight;
}

/**
 * 把 css对象转为字符串
 */
export function cssObj2Str(css: CSSProperties | string): string {
  // 字符串转字符串，对象转对象情形，直接返回
  if (typeof css === 'string') {
    return css;
  } else {
    let cssStr = '';
    for (const key in css) {
      cssStr += `${camelCase2KebabCase(key)}:${css[key as keyof typeof css]};`;
    }
    return cssStr;
  }
}

/**
 * 把带rpx 或 px 带单位的数字 转换为单位为 px 的数字
 * @param def - 转换失败是默认返回的值
 */
export function getXPNumber(str: string, def = 0): number {
  // 字符串转字符串，对象转对象情形，直接返回
  if (str.includes('rpx')) {
    return uni.upx2px(parseInt(str));
  } else if (str.includes('px')) {
    return parseInt(str);
  } else if (typeof str === 'number') {
    return str;
  } else {
    console.error('转换错误，非法单位');
    return def;
  }
}

/**
 * 得到动画
 */
export function getAmatons(mode: $AnimationMode, init: boolean): CSSProperties {
  let style: CSSProperties = {};
  if (mode === 'slide-top') {
    style = { opacity: init ? 1 : 0, transform: init ? 'translateY(0%)' : 'translateY(-100%)' };
  } else if (mode === 'slide-bottom') {
    style = { opacity: init ? 1 : 0, transform: init ? 'translateY(0%)' : 'translateY(100%)' };
  } else if (mode === 'slide-right') {
    style = { opacity: init ? 1 : 0, transform: init ? 'translateX(0%)' : 'translateX(100%)' };
  } else if (mode === 'slide-left') {
    style = { opacity: init ? 1 : 0, transform: init ? 'translateX(0%)' : 'translateX(-100%)' };
  } else if (mode === 'zoom-in') {
    style = { opacity: init ? 1 : 0, transform: init ? 'scale(1,1)' : 'scale(0.2,0.2)' };
  } else if (mode === 'zoom-out') {
    style = { opacity: init ? 1 : 0, transform: init ? 'scale(1,1)' : 'scale(1.8,1.8)' };
  } else if (mode === 'scale-top') {
    style = { transform: init ? 'scaleY(1)' : 'scaleY(0)', transformOrigin: 'center bottom', transitionProperty: 'transform' };
  } else if (mode === 'scale-bottom') {
    style = { transform: init ? 'scaleY(1)' : 'scaleY(0)', transformOrigin: 'center top', transitionProperty: 'transform' };
  } else if (mode === 'scale-left') {
    style = { transform: init ? 'scaleX(1)' : 'scaleX(0)', transformOrigin: 'right center', transitionProperty: 'transform' };
  } else if (mode === 'scale-right') {
    style = { transform: init ? 'scaleX(1)' : 'scaleX(0)', transformOrigin: 'left center', transitionProperty: 'transform' };
  } else {
    style = { opacity: init ? 1 : 0 };
  }
  return style;
}
